package com.xy.view;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.Scroller;

import java.lang.ref.WeakReference;
import java.lang.reflect.Field;

/**
 * Created by John on 2016/12/2.
 */

public class AutoScrollViewPager extends FrameLayout {

    private ViewPager vp;
    private boolean isAutoScroll = true;
    private boolean isCanTouchScroll = true;
    private Handler handler;
    private static final int SCROLL = 1;
    private int autoDelayScroll = 1200;
    private int delay = 1500;
    private ASScroller mScroller;
    private int LEFT = 0;
    private int RIGHT = 1;
    private int DERECTION = RIGHT;

    public AutoScrollViewPager(Context context) {
        this(context, null);
        init();
    }

    public AutoScrollViewPager(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public AutoScrollViewPager(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
        init();
    }

    private void init() {
        handler = new AutoScrollHandler(this);
        mScroller = new ASScroller(getContext(), sInterpolator);
    }

    public void setDerection(int DERECTION) {
        this.DERECTION = DERECTION;
    }

    public boolean isAutoScroll() {
        return isAutoScroll;
    }

    public void setAutoScroll(boolean autoScroll) {
        isAutoScroll = autoScroll;
    }

    public boolean isCanTouchScroll() {
        return isCanTouchScroll;
    }

    public void setCanTouchScroll(boolean canTouchScroll) {
        isCanTouchScroll = canTouchScroll;
    }


    public void setDelay(int delay) {
        this.delay = delay;
    }

    public void setAutoDelayScroll(int autoDelayScroll) {
        this.autoDelayScroll = autoDelayScroll;
    }

    private static final Interpolator sInterpolator = new Interpolator() {
        @Override
        public float getInterpolation(float t) {  //来自viewpager源码
            t -= 1.0f;
            return t * t * t * t * t + 1.0f;
        }
    };

    public void setPageMargin(int marginPixels){
        if (vp != null){
            vp.setPageMargin(marginPixels);
        }
    }

    public void setAdapter(AutoScrollPagerAdapter adapter) {
        stopScroll();
        if (vp != null) {
            removeView(vp);
        }
        vp = new ViewPager(getContext());
        addView(vp, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        vp.setAdapter(adapter);
        int index = adapter.getDataCount() != 0 ? (3000 / adapter.getDataCount()) * adapter.getDataCount() : 0;
        vp.setCurrentItem(index, false);
    }

    public void addOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
        if (vp != null) {
            vp.addOnPageChangeListener(listener);
        }
    }

    public  void stopScroll() {
        isAutoScroll = false;
        stop();
    }

    private void stop() {
        handler.removeMessages(SCROLL);
    }

    public void startScroll() {
        isAutoScroll = true;
        start();
    }

    private void start() {
        handler.removeMessages(SCROLL);
        handler.sendEmptyMessageDelayed(SCROLL, delay+autoDelayScroll);
    }

    private void scrollOnce() {
        if (vp != null) {
            setVPScroller(mScroller);
            mScroller.setDuration(autoDelayScroll);
            PagerAdapter adapter = vp.getAdapter();
            int currentItem = vp.getCurrentItem();
            int TotalCount = 0;
            if (adapter == null || (TotalCount = adapter.getCount()) <= 1) {
                return;
            }
            int nextItem = DERECTION == LEFT ? --currentItem : ++currentItem;
            if (nextItem < 0) {
                vp.setCurrentItem(TotalCount - 1, true);
            } else if (nextItem == TotalCount) {
                vp.setCurrentItem(0, true);
            } else {
                vp.setCurrentItem(nextItem, true);
            }
            mScroller.setDuration(-1);
        }
    }

    @Override
    protected void onWindowVisibilityChanged(int visibility) {
        super.onWindowVisibilityChanged(visibility);
        if (visibility == VISIBLE) {
            if (isAutoScroll) {
                start();
            }
        } else {
            stop();
            if (vp != null) {
                PagerAdapter adapter = vp.getAdapter();
                if (adapter != null) {
                    int currentItem = vp.getCurrentItem();
                    if (currentItem <= 0) {
                        currentItem = adapter.getCount();
                    }
                    vp.setCurrentItem(currentItem - 1, false);
                }
            }
        }
    }



    private boolean isStopWhenTouch = true;

    public boolean isStopWhenTouch() {
        return isStopWhenTouch;
    }

    public void setStopWhenTouch(boolean stopWhenTouch) {
        isStopWhenTouch = stopWhenTouch;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (isCanTouchScroll) {
            if (isStopWhenTouch) {
                if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
                    stop();
                } else if ((ev.getActionMasked() == MotionEvent.ACTION_DOWN || ev.getActionMasked() == MotionEvent.ACTION_UP || ev.getActionMasked() == MotionEvent.ACTION_OUTSIDE) && isAutoScroll) {
                    start();
                }
            }
            return super.dispatchTouchEvent(ev);
        } else{
            return false;  //返回给上层的onTouchEvent处理
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (isCanTouchScroll) {
            return super.onTouchEvent(event);
        } else {
            return false;
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (isAutoScroll) {
            start();
        }
    }


    @Override
    protected void onDetachedFromWindow() {
        stop();
        super.onDetachedFromWindow();
    }

    private static class AutoScrollHandler extends Handler {  //必须是静态的  不然会引发内存泄漏
        private WeakReference<AutoScrollViewPager> reference;

        public AutoScrollHandler(AutoScrollViewPager pager) {
            WeakReference<AutoScrollViewPager> reference = new WeakReference<>(pager);
            this.reference = reference;
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case SCROLL:
                    AutoScrollViewPager pager = reference.get();
                    if (pager != null){
                        pager.scrollOnce();
                        pager.startScroll();
                    }
                    break;
                default:
                    break;
            }
        }
    }

    private void setVPScroller(Scroller scroller) {
        try {
            Field field = ViewPager.class.getDeclaredField("mScroller");
            field.setAccessible(true);
            field.set(this.vp, scroller);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public class ASScroller extends Scroller {

        private int duration = 600;

        public ASScroller(Context context) {
            super(context);
        }

        public ASScroller(Context context, Interpolator interpolator) {
            super(context, interpolator);
        }

        public ASScroller(Context context, Interpolator interpolator, boolean flywheel) {
            super(context, interpolator, flywheel);
        }


        public void setDuration(int duration) {
            this.duration = duration;
        }

        @Override
        public void startScroll(int startX, int startY, int dx, int dy, int duration) {
            super.startScroll(startX, startY, dx, dy, this.duration > 0 ? this.duration : duration);
        }
    }

    public static abstract class AutoScrollPagerAdapter extends PagerAdapter {


        @Override
        public int getCount() {
            int length = getDataCount();
            if (length > 1) {
                return Integer.MAX_VALUE;
            } else if (length > 0) {
                return length;
            }
            return 0;
        }

        //获取数据总数
        public abstract int getDataCount();

        public abstract View createView(Context context, int position);

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            int dataCount = getDataCount();
            position %= dataCount;
            View view = createView(container.getContext(), position);
            container.addView(view);
            return view;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            View view = (View) object;
            container.removeView(view);
        }
    }
}
